home *** CD-ROM | disk | FTP | other *** search
- ; mode13h v0.90ß released 11-01-94
- ;
- ; 32 bit mode 13h graphics routines
- ; by Voltaire/OTM
- ; Copyright (C) 1994 Zach Mortensen
- ;
- ; email -
- ; mortens1@nersc.gov
- ;
- ; NOTE - These routines are designed to operate in the FLAT MEMORY
- ; MODEL ONLY! Therefore, you HAVE to be using protected mode to use
- ; them. If you're writing 32 bit code and NOT using protected mode,
- ; you should be slapped for your laziness and lack of foresight.
- ; Go spend $200 and buy Watcom C++ v10.0, it ROCKS, and it comes with
- ; DOS4GW, Rational Systems' 32 bit DOS extender. Will these routines
- ; work with Tran's PMODE? I DON'T KNOW. I picked up Tran's code long
- ; ago and found it impossible to use from within C++. I write all of
- ; my code in C++ with the exception of speed critical things like
- ; graphics primitives, and extremely low level code such as sound
- ; routines, which I do in assembler; so I never really gave PMODE
- ; much of a chance (sorry, Tran).
- ;
- ; DISCLAIMER - I am not an assembler programmer. I do not profess to
- ; be an assembler programmer. This code is all original. This code
- ; is all assembler. Therefore, this code CONTAINS SOME BUGS. I AM
- ; AWARE OF THAT. If you find any (and you will), please let me know.
- ; As far as optimization goes, I'm sure I've done a few things wrong
- ; here and there, but on the whole this is some pretty fast code. If
- ; you have any ideas on how to further optimize, please let me know
- ; as well.
- ;
-
-
- .386p
-
- .code
-
- ; Data goes here (in the CODE segment?!?! AAAAAAAAARRRGH!!)
-
-
- vidSeg dd 000A0000h
- virtPage dd ?
- curPage dd ?
- zBuf dd ?
-
-
- ; data for the triangle routines
-
- lEdge dd 200 dup(0)
- rEdge dd 200 dup(0)
- lColor dd 200 dup(0)
- rColor dd 200 dup(0)
- lZ dd 200 dup(0)
- rZ dd 200 dup(0)
-
- xTop dd 0
- yTop dd 0
- zTop dd 0
- cTop dd 0
- xMid dd 0
- yMid dd 0
- zMid dd 0
- cMid dd 0
- xBot dd 0
- yBot dd 0
- zBot dd 0
- cBot dd 0
-
- rCount dd 0
-
- temp dd 0
-
- zRatio dd 0 ; dzdx = constant for each poly
- cRatio dd 0 ; dcdx = constant for each poly
-
- xBres dd 0
- yBres dd 0
- cBres dd 0
-
- dxdy dd 0
-
- ; stuff for the regHline routine
-
- color dd 0
- scanLine dd 0
- rhlColor dd 0
-
- ; for tDrawBitmap routine
-
- sPos dd 0
- dPos dd 0
- xOffset dd 0
- yOffset dd 0
- oWidth dd 0 ; original width
- oHeight dd 0 ; original height
- nWidth dd 0 ; new width
- nHeight dd 0 ; new height
-
- ; table of colors (dwords) so we don't have to calculate them
- ; every time
-
- ; I never could get this to work the way I wanted it to...;)
-
- dwColor label dword
-
- dd 000000000h
- dd 001010101h, 002020202h, 003030303h, 004040404h
- dd 005050505h, 006060606h, 007070707h, 008080808h
- dd 009090909h, 00A0A0A0Ah, 00B0B0B0Bh, 00C0C0C0Ch
- dd 00D0D0D0Dh, 00E0E0E0Eh, 00F0F0F0Fh, 010101010h
- dd 011111111h, 012121212h, 013131313h, 014141414h
- dd 015151515h, 016161616h, 017171717h, 018181818h
- dd 019191919h, 01A1A1A1Ah, 01B1B1B1Bh, 01C1C1C1Ch
- dd 01D1D1D1Dh, 01E1E1E1Eh, 01F1F1F1Fh, 020202020h
- dd 021212121h, 022222222h, 023232323h, 024242424h
- dd 025252525h, 026262626h, 027272727h, 028282828h
- dd 029292929h, 02A2A2A2Ah, 02B2B2B2Bh, 02C2C2C2Ch
- dd 02D2D2D2Dh, 02E2E2E2Eh, 02F2F2F2Fh, 030303030h
- dd 031313131h, 032323232h, 033333333h, 034343434h
- dd 035353535h, 036363636h, 037373737h, 038383838h
- dd 039393939h, 03A3A3A3Ah, 03B3B3B3Bh, 03C3C3C3Ch
- dd 03D3D3D3Dh, 03E3E3E3Eh, 03F3F3F3Fh, 040404040h
- dd 041414141h, 042424242h, 043434343h, 044444444h
- dd 045454545h, 046464646h, 047474747h, 048484848h
- dd 049494949h, 04A4A4A4Ah, 04B4B4B4Bh, 04C4C4C4Ch
- dd 04D4D4D4Dh, 04E4E4E4Eh, 04F4F4F4Fh, 050505050h
- dd 051515151h, 052525252h, 053535353h, 054545454h
- dd 055555555h, 056565656h, 057575757h, 058585858h
- dd 059595959h, 05A5A5A5Ah, 05B5B5B5Bh, 05C5C5C5Ch
- dd 05D5D5D5Dh, 05E5E5E5Eh, 05F5F5F5Fh, 060606060h
- dd 061616161h, 062626262h, 063636363h, 064646464h
- dd 065656565h, 066666666h, 067676767h, 068686868h
- dd 069696969h, 06A6A6A6Ah, 06B6B6B6Bh, 06C6C6C6Ch
- dd 06D6D6D6Dh, 06E6E6E6Eh, 06F6F6F6Fh, 070707070h
- dd 071717171h, 072727272h, 073737373h, 074747474h
- dd 075757575h, 076767676h, 077777777h, 078787878h
- dd 079797979h, 07A7A7A7Ah, 07B7B7B7Bh, 07C7C7C7Ch
- dd 07D7D7D7Dh, 07E7E7E7Eh, 07F7F7F7Fh, 080808080h
- dd 081818181h, 082828282h, 083838383h, 084848484h
- dd 085858585h, 086868686h, 087878787h, 088888888h
- dd 089898989h, 08A8A8A8Ah, 08B8B8B8Bh, 08C8C8C8Ch
- dd 08D8D8D8Dh, 08E8E8E8Eh, 08F8F8F8Fh, 090909090h
- dd 091919191h, 092929292h, 093939393h, 094949494h
- dd 095959595h, 096969696h, 097979797h, 098989898h
- dd 099999999h, 09A9A9A9Ah, 09B9B9B9Bh, 09C9C9C9Ch
- dd 09D9D9D9Dh, 09E9E9E9Eh, 09F9F9F9Fh, 0A0A0A0A0h
- dd 0A1A1A1A1h, 0A2A2A2A2h, 0A3A3A3A3h, 0A4A4A4A4h
- dd 0A5A5A5A5h, 0A6A6A6A6h, 0A7A7A7A7h, 0A8A8A8A8h
- dd 0A9A9A9A9h, 0AAAAAAAAh, 0ABABABABh, 0ACACACACh
- dd 0ADADADADh, 0AEAEAEAEh, 0AFAFAFAFh, 0B0B0B0B0h
- dd 0B1B1B1B1h, 0B2B2B2B2h, 0B3B3B3B3h, 0B4B4B4B4h
- dd 0B5B5B5B5h, 0B6B6B6B6h, 0B7B7B7B7h, 0B8B8B8B8h
- dd 0B9B9B9B9h, 0BABABABAh, 0BBBBBBBBh, 0BCBCBCBCh
- dd 0BDBDBDBDh, 0BEBEBEBEh, 0BFBFBFBFh, 0C0C0C0C0h
- dd 0C1C1C1C1h, 0C2C2C2C2h, 0C3C3C3C3h, 0C4C4C4C4h
- dd 0C5C5C5C5h, 0C6C6C6C6h, 0C7C7C7C7h, 0C8C8C8C8h
- dd 0C9C9C9C9h, 0CACACACAh, 0CBCBCBCBh, 0CCCCCCCCh
- dd 0CDCDCDCDh, 0CECECECEh, 0CFCFCFCFh, 0D0D0D0D0h
- dd 0D1D1D1D1h, 0D2D2D2D2h, 0D3D3D3D3h, 0D4D4D4D4h
- dd 0D5D5D5D5h, 0D6D6D6D6h, 0D7D7D7D7h, 0D8D8D8D8h
- dd 0D9D9D9D9h, 0DADADADAh, 0DBDBDBDBh, 0DCDCDCDCh
- dd 0DDDDDDDDh, 0DEDEDEDEh, 0DFDFDFDFh, 0E0E0E0E0h
- dd 0E1E1E1E1h, 0E2E2E2E2h, 0E3E3E3E3h, 0E4E4E4E4h
- dd 0E5E5E5E5h, 0E6E6E6E6h, 0E7E7E7E7h, 0E8E8E8E8h
- dd 0E9E9E9E9h, 0EAEAEAEAh, 0EBEBEBEBh, 0ECECECECh
- dd 0EDEDEDEDh, 0EEEEEEEEh, 0EFEFEFEFh, 0F0F0F0F0h
- dd 0F1F1F1F1h, 0F2F2F2F2h, 0F3F3F3F3h, 0F4F4F4F4h
- dd 0F5F5F5F5h, 0F6F6F6F6h, 0F7F7F7F7h, 0F8F8F8F8h
- dd 0F9F9F9F9h, 0FAFAFAFAh, 0FBFBFBFBh, 0FCFCFCFCh
- dd 0FDFDFDFDh, 0FEFEFEFEh, 0FFFFFFFFh
-
-
-
-
- ; Code starts here
-
- ;----------------------------------------------
- ; void setMode13h(char *vPage)
- ;----------------------------------------------
- ;
- ; Sets the video mode to 320x200x256 (REAL hard), and sets up page flipping,
- ; if you want to use it. Sometimes (e.g. texture mappint) it's faster to
- ; write to the VGA one pixel at a time than it is to flip pages...don't ask
- ; me why.
- ;
- ; vPage = pointer to a buffer YOU have already allocated, better make it
- ; 64000 bytes (320x200) ... or MORE if you are in a generous mood. I do this
- ; so you can access the virtual page from higher level code if you wish.
- ; The virtual page facilitates off screen drawing (should you set the active
- ; page to pVirtual (or 1)), which eliminates screen flicker and in most cases
- ; makes your animation appear to be smoother. The virtual page tends to slow
- ; down gouraud shading and other drawing operations that write to the VGA
- ; one pixel at a time and do some calculating in between pixels.
-
- sm13Stack struc
- dd ?,? ; ebp, edi
- dd ? ; caller
- zB dd ? ; pointer to z-buffer (128k)
- vPage dd ? ; pointer to virtual page
- sm13Stack ends
-
- public setMode13h
-
- setMode13h proc
-
- push ebp
- push edi
- mov ebp, esp
-
- mov eax, 13h
- int 10h
-
- mov eax, [ebp].vPage
- mov virtPage, eax
- mov eax, vidSeg
- mov curPage, eax
-
- mov eax, [ebp].zB
- mov zBuf, eax
-
- mov eax, 0
- mov edi, virtPage
- mov ecx, 16000
- rep stosd
-
- mov edi, vidSeg
- mov ecx, 16000
- rep stosd
-
- mov edi, zBuf
- mov eax, 07FFF7FFFh
- mov ecx, 32000
- rep stosd
-
- pop edi
- pop ebp
-
- ret 4
-
- setMode13h endp
-
- ;--------------------
- ; void textMode(void)
- ;--------------------
- ;
- ; gets you back to 80x25...
- ;
-
- public textMode
-
- textMode proc
-
- mov eax, 3
- int 10h
-
- ret
-
- textMode endp
-
- ;--------------------------------------
- ;void setActivePage(int page)
- ;--------------------------------------
- ;
- ; Sets the page to be used for drawing, either the phyisical page (const
- ; pPhysical) or virtual page (const pVirtual). REMEMBER that if you draw
- ; to the virtual page, you need to display it (flipVPage()) before you can
- ; see it. Calling flipVPage() will copy the contents of the virtual page
- ; to the screen, regardless of which page is active, and does NOTHING else.
- ;
-
-
- sapStack struc
- dd ?,? ; room for registers
- dd ? ; caller
- aPage dd ? ; new active page
- sapStack ends
-
- public setActivePage
-
- setActivePage proc
-
- push ebp
- push edi
-
- mov ebp, esp
-
- mov eax, [ebp].aPage
- cmp eax, 0
- jne sapVPage
-
- mov eax, vidSeg
- mov curPage, eax
- jmp sapDone
-
- sapVPage:
-
- mov eax, virtPage
- mov curPage, eax
-
- sapDone:
-
- pop edi
- pop ebp
-
- ret 4
-
- setActivePage endp
-
-
- ;---------------------
- ; void flipVPage(void)
- ;---------------------
- ;
- ; flips the virtual page to the screen, displays what you have been drawing
- ; off screen.
-
-
- public flipVPage
-
- flipVPage proc
-
- push edi
- push esi
-
- call syncDisplay
-
- mov esi, virtPage
- mov edi, vidSeg
- mov ecx, 16000
-
- cld
- rep movsd
-
- pop esi
- pop edi
-
- ret
-
- flipVPage endp
-
-
- ; hline procedure used in poly filling, if you want to slow things down by
- ; calling it. The poly3 function makes use of an inline version of this
- ; procedure which eliminates the stack pushes and calls.
-
-
- hlStack struc
- dd ?,? ; room for regs
- dd ? ; caller
- hlcolor db ?,?,?,? ; color
- hly dd ? ; y
- hlx2 dd ? ; x2
- hlx1 dd ? ; x1
- hlStack ends
-
- public hline
-
- hline proc
-
- push ebp
- push edi
- mov ebp, esp
-
- mov eax, [ebp].hly
- mov ebx, 320
- mul ebx
-
- mov edi, curPage
-
- mov ecx, [ebp].hlx1
- mov ebx, [ebp].hlx2
-
- cmp ebx, ecx
- jg hlDraw
- xchg ebx, ecx
-
- hlDraw: add eax, ecx
- add edi, eax
-
- sub ebx, ecx
- mov ecx, ebx
- and ebx, 3
- shr ecx, 2
-
- mov ah, [ebp].hlcolor
- mov al, ah
- movzx edx, ax
- shl eax, 16
- or eax, edx
-
- cld
- rep stosd
- mov ecx, ebx
- rep stosb
-
- pop edi
- pop ebp
-
- ret 16
-
- hline endp
-
- ;----------------------------------------
- ; void setPixel(int x, int y, int color)
- ;----------------------------------------
- ;
- ; Sets the pixel at (x, y) to color (color). Does bounds checking to avoid
- ; the dreaded GP FAULT!
- ;
-
-
- spStack struc
- dd ?,? ; ebp, edi
- dd ? ; caller
- setpColor dd ? ; color of pixel
- setpY dd ? ; Y value
- setpX dd ? ; X value
- spStack ends
-
- public setPixel
-
- setPixel proc
-
- push ebp
- push edi
- mov ebp, esp
-
- mov eax, [ebp].setpY
- mov ecx, [ebp].setpX
-
- cmp eax, 0
- jl setPixDone
- cmp eax, 199
- jg setPixDone
- cmp ecx, 0
- jl setPixDone
- cmp ecx, 319
- jg setPixDone
-
- mov ebx, 320
- mul ebx
- add eax, ecx
-
- mov edi, eax
- add edi, curPage
-
- mov eax, [ebp].setpColor
- stosb
-
- setPixDone:
- pop edi
- pop ebp
-
- ret 12
-
- setPixel endp
-
- ;-----------------------
- ; void syncDisplay(void)
- ;-----------------------
- ;
- ; waits for the current vertical retrace to end, then waits for the start
- ; of the next one.
- ;
-
- public syncDisplay
-
- syncDisplay proc
-
- mov dx, 03DAh
-
- wait0:
- in al, dx
- test al, 08h
- jnz wait0
-
- wait1:
- in al, dx
- test al, 08h
- jz wait1
-
- ret
-
- syncDisplay endp
-
-
- ; a few basic mouse routines...I never implemented anything more in this
- ; library. Mice are easy, just refer to any interrupt listing for help.
-
- public initMouse
-
- initMouse proc
-
- mov ax, 0
- int 33h
-
- ret
-
- initMouse endp
-
- public showMouse
-
- showMouse proc
-
- mov ax, 1
- int 33h
-
- ret
-
- showMouse endp
-
- public hideMouse
-
- hideMouse proc
-
- mov ax, 2
- int 33h
-
- ret
-
- hideMouse endp
-
-
- ;----------------------------------------------------------------------------
- ; void poly3(int x1, int y1, int x2, int y2, int x3, int y3, int c);
- ;----------------------------------------------------------------------------
- ;
- ; Draws a clipped triangular polygon bounded by (x1,y1) (x2,y2) (x3,y3)
- ; in color c. This routine does NOT do shading!
- ;
-
-
- p3Stack struc
- dd ?,?,? ; room for regs
- dd ? ; caller
- p3color db ?,?,?,? ; color to fill
- p3y3 dd ? ; y3
- p3x3 dd ? ; x3
- p3y2 dd ? ; y2
- p3x2 dd ? ; x2
- p3y1 dd ? ; y1
- p3x1 dd ? ; x1
-
- p3Stack ends
-
- public poly3
-
- poly3 proc
-
- push ebp
- push edi
- push esi
-
- mov ebp, esp
-
- mov eax, [ebp].p3y1
- mov ebx, [ebp].p3y2
- mov ecx, [ebp].p3y3
-
- ; sort the points based on y values
-
- yComp1: cmp eax, ebx
- jg y2top
-
- mov yTop, eax
- mov edx, [ebp].p3x1
- mov xTop, edx
-
- mov yBot, ebx
- mov edx, [ebp].p3x2
- mov xBot, edx
-
- jmp yComp2
-
- y2top: mov yTop, ebx
- mov edx, [ebp].p3x2
- mov xTop, edx
-
- mov yBot, eax
- mov edx, [ebp].p3x1
- mov xBot, edx
-
- yComp2: cmp ecx, yTop
- jg yTopOK
-
- mov yTop, ecx
- mov edx, [ebp].p3x3
- mov xTop, edx
-
- cmp eax, ebx
- jg y2mid
-
- mov yMid, eax
- mov edx, [ebp].p3x1
- mov xMid, edx
-
- mov yBot, ebx
- mov edx, [ebp].p3x2
- mov xBot, edx
-
- jmp yCompDone
-
- y2mid: mov yMid, ebx
- mov edx, [ebp].p3x2
- mov xMid, edx
-
- mov yBot, eax
- mov edx, [ebp].p3x1
- mov xBot, edx
-
- jmp yCompDone
-
- yTopOK: cmp ecx, yBot
- jg ybBad
-
- mov yMid, ecx
- mov edx, [ebp].p3x3
- mov xMid, edx
-
- jmp yCompDone
-
- ybBad: mov eax, yBot
- mov ebx, xBot
-
- mov yMid, eax
- mov xMid, ebx
-
- mov yBot, ecx
- mov edx, [ebp].p3x3
- mov xBot, edx
-
- yCompDone:
-
- mov eax, yTop
- mov ebx, yBot
- cmp eax, 199
- jg fillDone
- cmp ebx, 0
- jl fillDone
-
- ; now calculate the x values at each scanline for the longest side.
-
- mov eax, xBot
- mov ebx, xTop
- sub eax, ebx
- shl eax, 16
-
- mov ecx, yBot
- mov edx, yTop
- sub ecx, edx
-
- jecxz edge1Horz ; skip the div if denominator = 0
- cmp eax, 0
- jge edge1Pos
-
- neg eax
- xor edx, edx
- div ecx
- neg eax
-
- jmp edge1Continue
-
- edge1Horz:
- ;xor eax, eax
- ;xor edx, edx
- ;jmp edge1Continue
-
- jmp edge2Start
-
- edge1Pos:
- xor edx, edx
- div ecx
-
- edge1Continue:
- mov ecx, yBot
- mov ebx, yTop
- sub ecx, ebx
-
- shl ebx, 2
- lea edi, lEdge
- add edi, ebx
-
- xor ebx, ebx
- mov edx, xTop
- mov esi, yTop
-
- align 4
-
- edge1Loop:
-
- cmp esi, 0
- jl skipThisLine1
- cmp esi, 199
- jg edge2Start
-
- ror ebx, 16
- add dx, bx
- movsx edx, dx
- rol ebx, 16
- movzx ebx, bx
- mov [edi], edx
-
- skipThisLine1:
- add ebx, eax
- add edi, 4
- inc esi
- dec ecx
- jns edge1Loop
-
- ; calculate x values for next side
-
- edge2Start:
- mov eax, xBot
- mov ebx, xMid
- sub eax, ebx
- shl eax, 16
-
- mov ecx, yBot
- mov edx, yMid
- sub ecx, edx
-
- jecxz edge2Horz
- cmp eax, 0
- jge edge2Pos
-
- neg eax
- xor edx, edx
- div ecx
- neg eax
- jmp edge2Continue
-
- edge2Horz:
- ;xor eax, eax
- ;xor edx, edx
- ;jmp edge2Continue
- jmp edge3Start
-
- edge2Pos:
- xor edx, edx
- div ecx
-
- edge2Continue:
- mov ecx, yBot
- mov ebx, yMid
- sub ecx, ebx
-
- shl ebx, 2
- lea edi, rEdge
- add edi, ebx
-
- xor ebx, ebx
- mov edx, xMid
- mov esi, yMid
-
- align 4
-
- edge2Loop:
-
- cmp esi, 0
- jl skipThisLine2
- cmp esi, 199
- jg edge3Start
-
- ror ebx, 16
- add dx, bx
- movsx edx, dx
- rol ebx, 16
- movzx ebx, bx
- mov [edi], edx
-
- skipThisLine2:
- add ebx, eax
- add edi, 4
- inc esi
- dec ecx
- jns edge2Loop
-
- ; calculate x values for last side
-
- edge3Start:
- mov eax, xMid
- mov ebx, xTop
- sub eax, ebx
- shl eax, 16
-
- mov ecx, yMid
- mov edx, yTop
- sub ecx, edx
-
- jecxz edge3Horz
- cmp eax, 0
- jge edge3Pos
-
- neg eax
- xor edx, edx
- div ecx
- neg eax
-
- jmp edge3Continue
-
- edge3Horz:
- ;xor eax, eax ; zero ratio
- ;xor edx, edx
- ;jmp edge3Continue
- jmp fillStart
-
- edge3Pos:
- xor edx, edx
- div ecx
-
- edge3Continue:
- mov ecx, yMid
- mov ebx, yTop
- sub ecx, ebx
-
- shl ebx, 2
- lea edi, rEdge
- add edi, ebx
-
- xor ebx, ebx
- mov edx, xTop
- mov esi, yTop
-
- align 4
-
- edge3Loop:
-
- cmp esi, 0
- jl skipThisLine3
- cmp esi, 199
- jg fillStart
-
- ror ebx, 16
- add dx, bx
- movsx edx, dx
- rol ebx, 16
- movzx ebx, bx
- mov [edi], edx
-
- skipThisLine3:
- add ebx, eax
- add edi, 4
- inc esi
- dec ecx
- jns edge3Loop
-
- ; time to fill...
-
- fillStart:
-
- mov eax, yTop
- mov ebx, yBot
-
- cmp eax, 0
- jge checkBot
- xor eax, eax
- mov yTop, eax
-
- checkBot:
- cmp ebx, 199
- jle fillNOW
- mov ebx, 199
- mov yBot, ebx
-
- fillNOW:
- lea esi, lEdge
- lea edi, rEdge
-
- mov dl, [ebp].p3color
- mov dh, dl
- movzx edx, dx
- mov eax, edx
- shl eax, 16
- or edx, eax
- mov rhlColor, edx
-
- mov ecx, yTop
- mov ebx, yBot
- shl ecx, 2
- add esi, ecx
- add edi, ecx
- shr ecx, 2
-
- align 4
-
- fillME: push ecx
-
- ; another way to draw the hline, with register calls rather than
- ; stack pushes to improve speed
- ;
- ; ON ENTRY
- ; [esi] = x1
- ; [edi] = x2
- ; ecx = y
- ; rhlColor = color to fill line with as a dword, that is, to draw
- ; a line of color 1, rhlColor would be 01010101
-
- ;public regHline
-
- mov eax, 320
- xor edx, edx
- mul ecx
-
- mov ecx, [esi]
- mov ebx, [edi]
-
- cmp ebx, ecx
- jg rhlDraw
- xchg ebx, ecx
-
- rhlDraw:
-
- cmp ecx, 319
- jg nextLine
-
- cmp ebx, 0
- jl nextLine
-
- checkX2:
- cmp ebx, 319
- jle checkX1
- mov ebx, 319
-
- checkX1:
- cmp ecx, 0
- jge x1OKToo
- xor ecx, ecx
-
- x1OKToo:
- push edi
- add eax, ecx
- mov edi, curPage
- add edi, eax
-
- sub ebx, ecx
- mov ecx, ebx
- and ebx, 3
- shr ecx, 2
-
- mov eax, rhlColor
-
- cld
- rep stosd
- mov ecx, ebx
- rep stosb
-
- pop edi
-
- ; end of the rhline proc (used to be a proc anyway...)
-
- nextLine:
- pop ecx
-
- add esi, 4
- add edi, 4
- inc ecx
- cmp ecx, yBot
- jg fillDone
- jmp fillME
-
- fillDone:
-
- pop esi
- pop edi
- pop ebp
-
- ret 28
-
- poly3 endp
-
- ;----------------------------
- ; void clearScreen(int color)
- ;----------------------------
- ;
- ; fills the screen with color (color). This is perhaps the most difficult
- ; thing I've ever written...heheh
- ;
-
- csStack struc
-
- dd ?,? ; ebp, edi
- dd ? ; caller
- csColor db ?,?,?,? ; color
-
- csStack ends
-
- public clearScreen
-
- clearScreen proc
-
- push ebp
- push edi
-
- mov ebp, esp
-
- mov edi, curPage
- mov ecx, 16000
- mov al, [ebp].csColor
- mov ah, al
- movzx edx, ax
- shl eax, 16
- or eax, edx
-
- rep stosd
-
- pop edi
- pop ebp
-
- ret 4
-
- clearScreen endp
-
-
- ; Palette routines courtesy of Matt Pritchard (MODEX). Something went wrong
- ; with the load_dac_registers routine in the conversion to 32 bit and pmode,
- ; and I haven't found the time to correct it yet...what a lazy bum I am!
- ; I've been using repeated calls to the set_dac_register routine instead...
-
- ;=================================================
- ;SET_DAC_REGISTER (Register%, Red%, Green%, Blue%)
- ;=================================================
- ;
- ; Sets a single (RGB) Vga Palette Register
- ;
- ; ENTRY: Register = The DAC # to modify (0-255)
- ; Red = The new Red Intensity (0-63)
- ; Green = The new Green Intensity (0-63)
- ; Blue = The new Blue Intensity (0-63)
- ;
- ; EXIT: No meaningful values returned
- ;
-
- SDR_STACK STRUC
- DD ? ; eBP
- DD ? ; Caller
- SDR_Blue DB ?,?,?,? ; Blue Data Value
- SDR_Green DB ?,?,?,? ; Green Data Value
- SDR_Red DB ?,?,?,? ; Red Data Value
- SDR_Register DB ?,?,?,? ; Palette Register #
- SDR_STACK ENDS
-
- PUBLIC SET_DAC_REGISTER
-
- SET_DAC_REGISTER PROC
-
- PUSH eBP ; Save BP
- MOV eBP, eSP ; Set up Stack Frame
-
- ; Select which DAC Register to modify
-
- mov dx, 03C8h
- mov al, [eBP].SDR_Register
- out dx, al
-
- MOV DX, 03C9h ; Dac Data Register
- mov al, [eBP].SDR_Red ; Set Red Intensity
- out dx, al
- mov al, [eBP].SDR_Green ; Set Green Intensity
- out dx, al
- mov al, [eBP].SDR_Blue ; Set Blue Intensity
- out dx, al
-
- POP eBP ; Restore Registers
- RET 16 ; Exit & Clean Up Stack
-
- SET_DAC_REGISTER ENDP
-
-
- ;===========================================================
- ;LOAD_DAC_REGISTERS (SEG PalData, StartReg%, EndReg%, Sync%)
- ;===========================================================
- ;
- ; Sets a Block of Vga Palette Registers
- ;
- ; ENTRY: PalData = Far Pointer to Block of palette data
- ; StartReg = First Register # in range to set (0-255)
- ; EndReg = Last Register # in Range to set (0-255)
- ; Sync = Wait for Vertical Retrace Flag (Boolean)
- ;
- ; EXIT: No meaningful values returned
- ;
- ; NOTES: PalData is a linear array of 3 byte Palette values
- ; in the order: Red (0-63), Green (0-63), Blue (0-63)
- ;
-
- LDR_STACK STRUC
- DD ?,? ; EBP, ESI
- DD ? ; Caller
- LDR_Sync DW ?,? ; Vertical Sync Flag
- LDR_EndReg DB ?,?,?,? ; Last Register #
- LDR_StartReg DB ?,?,?,? ; First Register #
- LDR_PalData DD ? ; Far Ptr to Palette Data
- LDR_STACK ENDS
-
- PUBLIC LOAD_DAC_REGISTERS
-
- LOAD_DAC_REGISTERS PROC
-
- PUSH ebp
- push esi ; Save Registers
- mov ebp, esp ; Set up Stack Frame
-
- mov AX, [BP].LDR_Sync ; Get Vertical Sync Flag
- or AX, AX ; is Sync Flag = 0?
- jz @LDR_Load ; if so, skip call
-
- call syncDisplay ; wait for vsync
-
- ; Determine register #'s, size to copy, etc
-
- @LDR_Load:
-
- mov esi, [BP].LDR_PalData ; DS:SI -> Palette Data
- mov DX, 03C8h ; DAC register # selector
-
- xor AX, ax
- xor BX, bx ; Clear for byte loads
- mov AL, [BP].LDR_StartReg ; Get Start Register
- mov BL, [BP].LDR_EndReg ; Get End Register
-
- sub BX, AX ; BX = # of DAC registers -1
- inc BX ; BX = # of DAC registers
- mov CX, BX ; CX = # of DAC registers
- add CX, BX ; CX = " " * 2
- add CX, BX ; CX = " " * 3
- cld ; Block OUTs forward
- out DX, AL ; set up correct register #
-
- ; Load a block of DAC Registers
-
- mov DX, 03C9h ; Dac Data Register
-
- rep outsb ; block set DAC registers
-
- POP esi
- pop ebp ; Restore Registers
-
- ret 20 ; Exit & Clean Up Stack
-
- LOAD_DAC_REGISTERS ENDP
-
- ;----------------------------------------------------
- ; void ghline(int x1, int c1, int x2, int c2, int y);
- ;----------------------------------------------------
- ;
- ; draws a horizontal line from (x1, y) to (x2, y) and interpolates colors
- ; (byte granularity) from c1 to c2 in the process. This is used to fill
- ; polygons in the gpoly3 routine. I really should make this an inline
- ; procedure like I did with hline, but the call is so much more complex...
- ; I figured it would take just about as long either way. Clipping too...
- ;
-
-
- ghlStack struc
-
- dd ?,?,? ; ebp esi edi
- dd ? ; caller
- ghly dd ? ; y
- ghlc2 dd ? ; c2
- ghlx2 dd ? ; x2
- ghlc1 dd ? ; c1
- ghlx1 dd ? ; x1
-
- ghlStack ends
-
- public gHline
-
- gHline proc ; gouraud hline routine
-
- push ebp
- push esi
- push edi
- mov ebp, esp
-
- mov eax, [ebp].ghly
- mov ebx, 320
- mul ebx
-
- mov edi, curPage
-
- mov ecx, [ebp].ghlx1
- mov ebx, [ebp].ghlx2
- mov esi, [ebp].ghlc1
- mov edx, [ebp].ghlc2
-
- cmp ebx, ecx
- jg ghlDraw
- xchg ebx, ecx
- xchg esi, edx
-
- ghlDraw:
- mov [ebp].ghlc2, edx
-
- cmp ecx, 0
- jge ghlx1ok
- mov ecx, 0
-
- ghlx1ok:
- cmp ecx, 320
- jge ghldone
-
- cmp ebx, 319
- jl ghlx2ok
- mov ebx, 319
-
- ghlx2ok:
- cmp ebx, 0
- jl ghldone
-
-
- add eax, ecx
- add edi, eax
-
- sub ebx, ecx
- mov ecx, ebx
-
- jecxz ghlIHATESHORTJUMPS
-
- ; and ebx, 3
- ; shr ecx, 2
-
-
-
-
- mov eax, edx
- sub eax, esi
- shl eax, 8 ; dc *= 256
- xor edx, edx
-
- cmp eax, 0
- jl ghlNeg
- div ebx ; get dcdx
- jmp ghlGoOn
-
- ghlIHATESHORTJUMPS:
- jmp ghlDone
-
- ghlNeg:
- neg eax
- div ebx
- neg eax
-
- ghlGoOn:
- mov edx, eax ; edx = dcdx * 256
- mov ebx, esi ; eax = c1
- shl ebx, 8 ; ebx *= 256
-
- ;mov esi, ecx
- ;and esi, 7
- ;shr ecx, 3
-
- cld
- align 4
-
- ghlLoop:
- jcxz ghlMod
-
- mov [edi], bh
- inc edi
- add ebx, edx
-
- dec ecx
- jmp ghlLoop
-
- ghlMod:
- ;mov ecx, esi
- ;rep stosb
-
- ghlDone:
- pop edi
- pop esi
- pop ebp
-
- ret 20
-
-
- gHline endp
-
-
- ;----------------------------------------------------------------------------
- ; void gpoly3(int x1, int y1, int c1, int x2, int y2, int c2, int x3, int y3,
- ; int c3);
- ;----------------------------------------------------------------------------
- ;
- ; Draws a fully clipped gouraud shaded polygon at the given coordinates and
- ; colors. If you don't understand the concept behind gouraud shading, this
- ; is not the place to learn. Send email.
- ;
-
-
- gp3Stack struc
- dd ?,?,? ; room for regs
- dd ? ; caller
- gp3c3 dd ? ; c3
- gp3y3 dd ? ; y3
- gp3x3 dd ? ; x3
- gp3c2 dd ? ; c2
- gp3y2 dd ? ; y2
- gp3x2 dd ? ; x2
- gp3c1 dd ? ; c1
- gp3y1 dd ? ; y1
- gp3x1 dd ? ; x1
-
- gp3Stack ends
-
- public gpoly3
-
- gpoly3 proc
-
- push ebp
- push edi
- push esi
-
- mov ebp, esp
-
- mov eax, [ebp].gp3y1
- mov ebx, [ebp].gp3y2
- mov ecx, [ebp].gp3y3
-
- ; sort the points based on y values
-
- gyComp1:
- cmp eax, ebx
- jg gy2top
-
- mov yTop, eax
- mov edx, [ebp].gp3x1
- mov xTop, edx
- mov edx, [ebp].gp3c1
- mov cTop, edx
-
- mov yBot, ebx
- mov edx, [ebp].gp3x2
- mov xBot, edx
- mov edx, [ebp].gp3c2
- mov cBot, edx
-
- jmp gyComp2
-
- gy2top: mov yTop, ebx
- mov edx, [ebp].gp3x2
- mov xTop, edx
- mov edx, [ebp].gp3c2
- mov cTop, edx
-
- mov yBot, eax
- mov edx, [ebp].gp3x1
- mov xBot, edx
- mov edx, [ebp].gp3c1
- mov cBot, edx
-
- gyComp2:
- cmp ecx, yTop
- jg gyTopOK
-
- mov yTop, ecx
- mov edx, [ebp].gp3x3
- mov xTop, edx
- mov edx, [ebp].gp3c3
- mov cTop, edx
-
- cmp eax, ebx
- jg gy2mid
-
- mov yMid, eax
- mov edx, [ebp].gp3x1
- mov xMid, edx
- mov edx, [ebp].gp3c1
- mov cMid, edx
-
- mov yBot, ebx
- mov edx, [ebp].gp3x2
- mov xBot, edx
- mov edx, [ebp].gp3c2
- mov cBot, edx
-
-
- jmp gyCompDone
-
- gy2mid: mov yMid, ebx
- mov edx, [ebp].gp3x2
- mov xMid, edx
- mov edx, [ebp].gp3c2
- mov cMid, edx
-
- mov yBot, eax
- mov edx, [ebp].gp3x1
- mov xBot, edx
- mov edx, [ebp].gp3c1
- mov cBot, edx
-
- jmp gyCompDone
-
- gyTopOK:
- cmp ecx, yBot
- jg gybBad
-
- mov yMid, ecx
- mov edx, [ebp].gp3x3
- mov xMid, edx
- mov edx, [ebp].gp3c3
- mov cMid, edx
-
- jmp gyCompDone
-
- gybBad: mov eax, yBot
- mov ebx, xBot
- mov edx, cBot
-
- mov yMid, eax
- mov xMid, ebx
- mov cMid, edx
-
- mov yBot, ecx
- mov edx, [ebp].gp3x3
- mov xBot, edx
- mov edx, [ebp].gp3c3
- mov cBot, edx
-
-
- gyCompDone:
-
- mov eax, yTop
- mov ebx, yBot
- cmp eax, 199
- jg gfillDone
- cmp ebx, 0
- jl gfillDone
-
- ; now calculate the x values at each scanline for the longest side.
-
- mov eax, xBot
- mov ebx, xTop
- sub eax, ebx
- shl eax, 16
-
- mov ecx, yBot
- mov edx, yTop
- sub ecx, edx
-
- jecxz gedge1Horz ; skip the div if denominator = 0
- cmp eax, 0
- jge gedge1Pos
-
- neg eax
- xor edx, edx
- div ecx
- neg eax
-
- jmp gedge1Continue
-
- gedge1Horz:
- ;xor eax, eax
- ;xor edx, edx
- ;jmp gedge1Continue
-
- jmp gedge2Start
-
- gedge1Pos:
- xor edx, edx
- div ecx
-
- gedge1Continue:
- mov ecx, yBot
- mov ebx, yTop
- sub ecx, ebx
-
- shl ebx, 2
- lea edi, lEdge
- add edi, ebx
-
- xor ebx, ebx
- mov edx, xTop
- mov esi, yTop
-
- align 4
-
- gedge1Loop:
-
- cmp esi, 0
- jl gskipThisLine1
- cmp esi, 199
- jg gedge2Start
-
- ror ebx, 16
- add dx, bx
- movsx edx, dx
- rol ebx, 16
- movzx ebx, bx
- mov [edi], edx
-
- gskipThisLine1:
- add ebx, eax
- add edi, 4
- inc esi
- dec ecx
- jns gedge1Loop
-
- ; calculate x values for next side
-
- gedge2Start:
- mov eax, xBot
- mov ebx, xMid
- sub eax, ebx
- shl eax, 16
-
- mov ecx, yBot
- mov edx, yMid
- sub ecx, edx
-
- jecxz gedge2Horz
- cmp eax, 0
- jge gedge2Pos
-
- neg eax
- xor edx, edx
- div ecx
- neg eax
- jmp gedge2Continue
-
- gedge2Horz:
- ;xor eax, eax
- ;xor edx, edx
- ;jmp gedge2Continue
- jmp gedge3Start
-
- gedge2Pos:
- xor edx, edx
- div ecx
-
- gedge2Continue:
- mov ecx, yBot
- mov ebx, yMid
- sub ecx, ebx
-
- shl ebx, 2
- lea edi, rEdge
- add edi, ebx
-
- xor ebx, ebx
- mov edx, xMid
- mov esi, yMid
-
- align 4
-
- gedge2Loop:
-
- cmp esi, 0
- jl gskipThisLine2
- cmp esi, 199
- jg gedge3Start
-
- ror ebx, 16
- add dx, bx
- movsx edx, dx
- rol ebx, 16
- movzx ebx, bx
- mov [edi], edx
-
- gskipThisLine2:
- add ebx, eax
- add edi, 4
- inc esi
- dec ecx
- jns gedge2Loop
-
- ; calculate x values for last side
-
- gedge3Start:
- mov eax, xMid
- mov ebx, xTop
- sub eax, ebx
- shl eax, 16
-
- mov ecx, yMid
- mov edx, yTop
- sub ecx, edx
-
- jecxz gedge3Horz
- cmp eax, 0
- jge gedge3Pos
-
- neg eax
- xor edx, edx
- div ecx
- neg eax
-
- jmp gedge3Continue
-
- gedge3Horz:
- ;xor eax, eax ; zero ratio
- ;xor edx, edx
- ;jmp gedge3Continue
- jmp gcolorStartc
-
- gedge3Pos:
- xor edx, edx
- div ecx
-
- gedge3Continue:
- mov ecx, yMid
- mov ebx, yTop
- sub ecx, ebx
-
- shl ebx, 2
- lea edi, rEdge
- add edi, ebx
-
- xor ebx, ebx
- mov edx, xTop
- mov esi, yTop
-
- align 4
-
- gedge3Loop:
-
- cmp esi, 0
- jl gskipThisLine3
- cmp esi, 199
- jg gcolorStartc
-
- ror ebx, 16
- add dx, bx
- movsx edx, dx
- rol ebx, 16
- movzx ebx, bx
- mov [edi], edx
-
- gskipThisLine3:
- add ebx, eax
- add edi, 4
- inc esi
- dec ecx
- jns gedge3Loop
-
- gcolorStartc:
-
- ; now calculate the color values at each scanline for the longest side.
-
- mov eax, cBot
- mov ebx, cTop
- sub eax, ebx
- shl eax, 16
-
- mov ecx, yBot
- mov edx, yTop
- sub ecx, edx
-
- jecxz gedge1Horzc ; skip the div if denominator = 0
- cmp eax, 0
- jge gedge1Posc
-
- neg eax
- xor edx, edx
- div ecx
- neg eax
-
- jmp gedge1Continuec
-
- gedge1Horzc:
- ;xor eax, eax
- ;xor edx, edx
- ;jmp gedge1Continuec
-
- jmp gedge2Startc
-
- gedge1Posc:
- xor edx, edx
- div ecx
-
- gedge1Continuec:
- mov ecx, yBot
- mov ebx, yTop
- sub ecx, ebx
-
- shl ebx, 2
- lea edi, lColor
- add edi, ebx
-
- xor ebx, ebx
- mov edx, cTop
- mov esi, yTop
-
- align 4
-
- gedge1Loopc:
-
- cmp esi, 0
- jl gskipThisLine1c
- cmp esi, 199
- jg gedge2Startc
-
- ror ebx, 16
- add dx, bx
- movsx edx, dx
- rol ebx, 16
- movzx ebx, bx
- mov [edi], edx
-
- gskipThisLine1c:
- add ebx, eax
- add edi, 4
- inc esi
- dec ecx
- jns gedge1Loopc
-
- ; calculate x values for next side
-
- gedge2Startc:
- mov eax, cBot
- mov ebx, cMid
- sub eax, ebx
- shl eax, 16
-
- mov ecx, yBot
- mov edx, yMid
- sub ecx, edx
-
- jecxz gedge2Horzc
- cmp eax, 0
- jge gedge2Posc
-
- neg eax
- xor edx, edx
- div ecx
- neg eax
- jmp gedge2Continuec
-
- gedge2Horzc:
- ;xor eax, eax
- ;xor edx, edx
- ;jmp gedge2Continuec
- jmp gedge3Startc
-
- gedge2Posc:
- xor edx, edx
- div ecx
-
- gedge2Continuec:
- mov ecx, yBot
- mov ebx, yMid
- sub ecx, ebx
-
- shl ebx, 2
- lea edi, rColor
- add edi, ebx
-
- xor ebx, ebx
- mov edx, cMid
- mov esi, yMid
-
- align 4
-
- gedge2Loopc:
-
- cmp esi, 0
- jl gskipThisLine2c
- cmp esi, 199
- jg gedge3Startc
-
- ror ebx, 16
- add dx, bx
- movsx edx, dx
- rol ebx, 16
- movzx ebx, bx
- mov [edi], edx
-
- gskipThisLine2c:
- add ebx, eax
- add edi, 4
- inc esi
- dec ecx
- jns gedge2Loopc
-
- ; calculate x values for last side
-
- gedge3Startc:
- mov eax, cMid
- mov ebx, cTop
- sub eax, ebx
- shl eax, 16
-
- mov ecx, yMid
- mov edx, yTop
- sub ecx, edx
-
- jecxz gedge3Horzc
- cmp eax, 0
- jge gedge3Posc
-
- neg eax
- xor edx, edx
- div ecx
- neg eax
-
- jmp gedge3Continuec
-
- gedge3Horzc:
- ;xor eax, eax ; zero ratio
- ;xor edx, edx
- ;jmp gedge3Continuec
- jmp gfillStart
-
- gedge3Posc:
- xor edx, edx
- div ecx
-
- gedge3Continuec:
- mov ecx, yMid
- mov ebx, yTop
- sub ecx, ebx
-
- shl ebx, 2
- lea edi, rColor
- add edi, ebx
-
- xor ebx, ebx
- mov edx, cTop
- mov esi, yTop
-
- align 4
-
- gedge3Loopc:
-
- cmp esi, 0
- jl gskipThisLine3c
- cmp esi, 199
- jg gfillStart
-
- ror ebx, 16
- add dx, bx
- movsx edx, dx
- rol ebx, 16
- movzx ebx, bx
- mov [edi], edx
-
- gskipThisLine3c:
- add ebx, eax
- add edi, 4
- inc esi
- dec ecx
- jns gedge3Loopc
-
-
- ; time to fill...
-
- gfillStart:
-
- mov eax, yTop
- mov ebx, yBot
-
- cmp eax, 0
- jge gcheckBot
- xor eax, eax
- mov yTop, eax
-
- gcheckBot:
- cmp ebx, 199
- jle gfillNOW
- mov ebx, 199
- mov yBot, ebx
-
- gfillNOW:
- lea esi, lEdge
- lea edi, rEdge
-
- lea eax, lColor
- lea edx, rColor
-
- mov ecx, yTop
- mov ebx, yBot
- shl ecx, 2
-
- add esi, ecx
- add edi, ecx
- add eax, ecx
- add edx, ecx
-
- shr ecx, 2
-
- align 4
-
- gfillME: push ecx
-
-
- grhlDraw:
-
- cmp ecx, 319
- jg gnextLine
-
- cmp ebx, 0
- jl gnextLine
-
- gcheckX2:
- cmp ebx, 319
- jle gcheckX1
- mov ebx, 319
-
- gcheckX1:
- cmp ecx, 0
- jge gx1OKToo
- xor ecx, ecx
-
- gx1OKToo:
- push esi
- push eax
- push edi
- push edx
-
- push [esi]
- push [eax]
- push [edi]
- push [edx]
- push ecx
-
- call gHline
-
- pop edx
- pop edi
- pop eax
- pop esi
-
- gnextLine:
- pop ecx
-
- add esi, 4
- add edi, 4
- add eax, 4
- add edx, 4
- inc ecx
- cmp ecx, yBot
- jg gfillDone
- jmp gfillME
-
- gfillDone:
-
- pop esi
- pop edi
- pop ebp
-
- ret 36
-
- gpoly3 endp
-
-
- ;--------------------------------------------------------------------
- ; void tDrawBitmap(char *image, int x, int y, int width, int height);
- ;--------------------------------------------------------------------
- ;
- ; draws a bitmapt to the screen, with color 0 transparent. Full clipping
- ; is done as an added bonus...
- ;
-
- tdbStack STRUC
-
- dd ?,?,? ; ebp, esi, edi
- dd ? ; caller
- tdbHeight dd ?
- tdbWidth dd ?
- tdbY dd ?
- tdbX dd ?
- tdbImage dd ?
-
- tdbStack ENDS
-
- public tDrawBitmap
-
- tDrawBitmap proc
-
- push edi
- push esi
- push ebp
-
- mov ebp, esp
-
- mov eax, 0
- mov sPos, eax
- mov xOffset, 0
- mov yOffset, 0
-
- mov esi, [ebp].tdbImage
- mov edi, curPage
- mov ecx, [ebp].tdbY
- mov eax, 320
- mul ecx
- mov edx, [ebp].tdbX
- add eax, edx
- mov dPos, eax
-
- mov ebx, [ebp].tdbWidth
- mov eax, [ebp].tdbHeight
- mov oWidth, ebx
- mov nWidth, ebx
- mov oHeight, eax
- mov nHeight, eax
-
- ; clipping action...
-
- cmp edx, 0
- jl tdbXNeg
-
- tdbCheckY:
- cmp ecx, 0
- jl tdbYNeg
-
- jmp tdbContinue
-
- tdbXNeg:
- neg edx
- cmp edx, ebx
- jg tdbDone ; bitmap is off screen if -x > width
- mov xOffset, edx ; store the offset
- neg edx ; back to negative...
- add nWidth, edx
-
- jmp tdbCheckY
-
- tdbYNeg:
- neg ecx
- cmp ecx, eax
- jge tdbDone ; bitmap is off screen if -y > height
- ;neg ecx
- ;add ecx, eax
- sub nHeight, ecx
- inc ecx
-
- tdbFixY:
- dec ecx
- cmp ecx, 0
- jle tdbContinue
- add dPos, 320 ; go to next line on screen
- add sPos, ebx ; go to next line in source
- jmp tdbFixY
-
- tdbContinue:
-
- mov ecx, [ebp].tdbY ; recharge ecx
-
- cmp ecx, 200 ;
- jg tdbDone
-
- cmp edx, 320 ;
- jg tdbDone
-
- add ebx, edx
- cmp ebx, 320 ;
- jg tdbXTooBig
-
- tdbCheckY2:
- add eax, ecx
- cmp eax, 200 ;
- ;cmp nHeight, 200
- jge tdbYTooBig
-
- jmp tdbClipDone
-
- tdbXTooBig:
- mov nWidth, ebx
- cmp edx, 0
- jge tdbXPos
-
- cmp nWidth, 320
- jl tdbClipDone
- mov nWidth, 320
- jmp tdbCheckY2
-
- ;mov ebx, 320
- ;sub ebx, edx
- ;cmp ebx, 320
- ;jl tdbXTooBig2
- ;mov ebx, 320
-
- tdbXPos:
- mov ebx, 320
- sub ebx, edx
- mov nWidth, ebx
- jmp tdbCheckY2
-
- tdbXTooBig2:
- ;mov nWidth, ebx
- ;jmp tdbCheckY2
-
- ;sub edx, 320 ;
- ;sub ebx, edx ; get new 'width'
- ;mov nWidth, ebx
- ;jmp tdbCheckY2
-
- tdbYTooBig:
- cmp ecx, 0
- jge tdbYPos
-
- cmp nHeight, 200
- jl tdbClipDone
- mov nHeight, 200
- jmp tdbClipDone
- ;cmp eax, 0
- ;jg tdbYTooBigPos
- ;mov eax, 200
- ;sub eax, ecx
- ;cmp eax, 200
- ;jl tdbYTooBig3
- ;mov eax, 200
- ;jmp tdbYTooBig3
-
- tdbYPos:
- mov eax, 200
- sub eax, ecx
- mov nHeight, eax
- jmp tdbClipDone
-
-
- tdbYTooBig3:
- ;mov nHeight, eax
- ;jmp tdbClipDone
-
- ;sub ecx, 200 ;
- ;sub eax, ecx ; get new 'height'
- ;mov nHeight, eax
- ;jmp tdbClipDone
-
- tdbClipDone:
-
- mov ecx, nHeight ; get 'height'
- cld
- mov edx, xOffset
- add sPos, edx
- add dPos, edx
-
- align 4
-
- tdbDrawLoop:
- mov esi, [ebp].tdbImage
- add esi, sPos
-
- mov edi, curPage
- add edi, dPos
-
- mov ebx, ecx
- mov ecx, nWidth
- mov edx, xOffset
- ;sub ecx, edx
-
- align 4
-
- tdbRowLoop:
-
- cmp ecx, 4
- jl tdbMod
-
- lodsd
-
- test al, 0FFh
- jz tdbPix2
- stosb
- dec edi
-
- tdbPix2:
- inc edi
- shr eax, 8
- test al, 0FFh
- jz tdbPix3
- stosb
- dec edi
-
- tdbPix3:
- inc edi
- shr eax, 8
- test al, 0FFh
- jz tdbPix4
- stosb
- dec edi
-
- tdbPix4:
- inc edi
- shr eax, 8
- test al, 0FFh
- jz tdbNextDW
- stosb
- dec edi
-
- tdbNextDW:
- inc edi
- sub ecx, 4
- jmp tdbRowLoop
-
- tdbMod:
- jecxz tdbRowDone
- lodsb
- test al, 0FFh
- jz tdbMod2
- stosb
- dec edi
-
- tdbMod2:
- inc edi
- dec ecx
- jecxz tdbRowDone
- lodsb
- test al, 0FFh
- jz tdbMod3
- stosb
- dec edi
-
- tdbMod3:
- inc edi
- dec ecx
- jecxz tdbRowDone
- lodsb
- test al, 0FFh
- jz tdbRowDone
- stosb
- dec edi
-
- tdbRowDone:
- inc edi
- mov ecx, ebx
- dec ecx
- mov ebx, oWidth
- add sPos, ebx
- add dPos, 320
- ; mov ebx, xOffset
- ; add dPos, ebx
- ; add sPos, ebx
-
- cmp ecx, 0
- jle tdbDone
-
- ;jecxz tdbDone
- jmp tdbDrawLoop
-
- tdbDone:
-
- pop ebp
- pop esi
- pop edi
-
- ret 20
-
-
- tDrawBitmap endp
-
-
- ;-------------------------------------------------------------------
- ; void drawBitmap(char *image, int x, int y, int width, int height);
- ;-------------------------------------------------------------------
- ;
- ; draws a bitmap to the screen. Full clipping once again...
- ;
-
-
- dbStack STRUC
-
- dd ?,?,? ; ebp, esi, edi
- dd ? ; caller
- dbHeight dd ?
- dbWidth dd ?
- dbY dd ?
- dbX dd ?
- dbImage dd ?
-
- dbStack ENDS
-
- public drawBitmap
-
- drawBitmap proc
-
- push edi
- push esi
- push ebp
-
- mov ebp, esp
-
- mov eax, 0
- mov sPos, eax
- mov xOffset, 0
- mov yOffset, 0
-
- mov esi, [ebp].dbImage
- mov edi, curPage
- mov ecx, [ebp].dbY
- mov eax, 320
- mul ecx
- mov edx, [ebp].dbX
- add eax, edx
- mov dPos, eax
-
- mov ebx, [ebp].dbWidth
- mov eax, [ebp].dbHeight
- mov oWidth, ebx
- mov nWidth, ebx
- mov oHeight, eax
- mov nHeight, eax
-
- ; clipping action...
-
- cmp edx, 0
- jl dbXNeg
-
- dbCheckY:
- cmp ecx, 0
- jl dbYNeg
-
- jmp dbContinue
-
- dbXNeg:
- neg edx
- cmp edx, ebx
- jg dbDone ; bitmap is off screen if -x > width
- mov xOffset, edx ; store the offset
- neg edx ; back to negative...
- add nWidth, edx
-
- jmp dbCheckY
-
- dbYNeg:
- neg ecx
- cmp ecx, eax
- jge dbDone ; bitmap is off screen if -y > height
- ;neg ecx
- ;add ecx, eax
- sub nHeight, ecx
- inc ecx
-
- dbFixY:
- dec ecx
- cmp ecx, 0
- jle dbContinue
- add dPos, 320 ; go to next line on screen
- add sPos, ebx ; go to next line in source
- jmp dbFixY
-
- dbContinue:
-
- mov ecx, [ebp].dbY ; recharge ecx
-
- cmp ecx, 200 ;
- jg dbDone
-
- cmp edx, 320 ;
- jg dbDone
-
- add ebx, edx
- cmp ebx, 320 ;
- jg dbXTooBig
-
- dbCheckY2:
- add eax, ecx
- cmp eax, 200 ;
- ;cmp nHeight, 200
- jge dbYTooBig
-
- jmp dbClipDone
-
- dbXTooBig:
- mov nWidth, ebx
- cmp edx, 0
- jge dbXPos
-
- cmp nWidth, 320
- jl dbClipDone
- mov nWidth, 320
- jmp dbCheckY2
-
- ;mov ebx, 320
- ;sub ebx, edx
- ;cmp ebx, 320
- ;jl dbXTooBig2
- ;mov ebx, 320
-
- dbXPos:
- mov ebx, 320
- sub ebx, edx
- mov nWidth, ebx
- jmp dbCheckY2
-
- dbXTooBig2:
- ;mov nWidth, ebx
- ;jmp dbCheckY2
-
- ;sub edx, 320 ;
- ;sub ebx, edx ; get new 'width'
- ;mov nWidth, ebx
- ;jmp dbCheckY2
-
- dbYTooBig:
- cmp ecx, 0
- jge dbYPos
-
- cmp nHeight, 200
- jl dbClipDone
- mov nHeight, 200
- jmp dbclipDone
- ;cmp eax, 0
- ;jg dbYTooBigPos
- ;mov eax, 200
- ;sub eax, ecx
- ;cmp eax, 200
- ;jl dbYTooBig3
- ;mov eax, 200
- ;jmp dbYTooBig3
-
- dbYPos:
- mov eax, 200
- sub eax, ecx
- mov nHeight, eax
- jmp dbclipDone
-
-
- dbYTooBig3:
- ;mov nHeight, eax
- ;jmp dbClipDone
-
- ;sub ecx, 200 ;
- ;sub eax, ecx ; get new 'height'
- ;mov nHeight, eax
- ;jmp dbClipDone
-
- dbClipDone:
-
- mov ecx, nHeight ; get 'height'
- cld
- mov edx, xOffset
- add sPos, edx
- add dPos, edx
-
- align 4
-
- dbDrawLoop:
- mov esi, [ebp].dbImage
- add esi, sPos
-
- mov edi, curPage
- add edi, dPos
-
- mov ebx, ecx
- mov ecx, nWidth
- mov edx, xOffset
- ;sub ecx, edx
-
- dbRowLoop:
-
- mov edx, ecx
- shr ecx, 2
- and edx, 3
-
- cmp ecx, 0
- jle dbMod
-
- rep movsd
-
- dbMod:
- mov ecx, edx
- rep movsb
-
-
- dbRowDone:
- mov ecx, ebx
- dec ecx
- mov ebx, oWidth
- add sPos, ebx
- add dPos, 320
- ; mov ebx, xOffset
- ; add dPos, ebx
- ; add sPos, ebx
-
- cmp ecx, 0
- jle dbDone
-
- ;jecxz dbDone
- jmp dbDrawLoop
-
- dbDone:
-
- pop ebp
- pop esi
- pop edi
-
- ret 20
-
-
- drawBitmap endp
-
- ; NOTE: clearing the ENTIRE z-buffer is a very slow way of doing things. I
- ; have implemented a system of z-buffer checking that eliminates this time
- ; consuming step, given a certain range of background colors. In the hline
- ; routines, I do a TEST on screen location I am about to write to. Right now,
- ; I draw to the screen without checking the z-buffer if the current pixel is
- ; color 0. This can easily be modified to give an acceptable range of
- ; background colors. For example, if you want to have 16 background colors,
- ; replace the test BYTE PTR [edi], 0FFh with test BYTE PTR [edi], 0F0h. This
- ; will eliminate z-buffer checking for all colors < 16, so you would be free
- ; to use colors 0-15 in your background. If all of this is too confusing,
- ; remove the test/jz pair from the inner loop and just call clearZBuf before
- ; you start drawing a new frame.
-
-
- public clearZBuf
-
- clearZBuf proc
-
- push edi
-
- mov edi, zBuf ; get address of z-buffer
- mov ecx, 32000 ; store 32000 dwords (128000 bytes)
- mov eax, 07FFF7FFFh ; fill two words at once with 7fffh (32767,
- ; greatest 16 bit signed quantity)
-
- cld ; clear direction flag for forward writes
- rep stosd ; and...GO
-
- pop edi
-
- ret
-
- clearZBuf endp
-
-
- ; OK, here is where the nice, commented code starts ;) Everything up to this
- ; point is either very basic, or is extended in the following four procedures.
- ; Everything up until this point is also fairly unoptimized, I spent all my
- ; time optimizing the code I planned on using. The most noticable difference
- ; in the z-buffered polygon routines is faster scan conversion.
-
-
- zhlStack struc
-
- dd ?,?,? ; ebp esi edi
- dd ? ; caller
- zhlc dd ? ; color
- zhly dd ? ; y
- zhlz2 dd ? ; z2
- zhlx2 dd ? ; x2
- zhlz1 dd ? ; z1
- zhlx1 dd ? ; x1
-
- zhlStack ends
-
- public zHline
-
- zHline proc ; zbuffered hline routine
-
- push ebp
- push esi
- push edi
- mov ebp, esp
-
- mov eax, [ebp].zhlc ; get color
- mov cTop, eax ; store the color (kludgy? I don't care ;))
-
- mov eax, [ebp].zhly ; get y value
-
- lea eax, [eax + eax * 4] ; use lea to do a fast multiply
- shl eax, 6 ; now eax = eax * 320
-
- mov edi, curPage ; get address of current page
-
- mov ecx, [ebp].zhlx1 ; load x and z values
- mov ebx, [ebp].zhlx2
- mov esi, [ebp].zhlz1
- mov edx, [ebp].zhlz2
-
- movsx ecx, cx ; sign extend 16 bit values into 32 bit regs
- movsx ebx, bx
- movsx esi, si
- movsx edx, dx
-
- cmp ebx, ecx ; make sure x2 > x1
- jg zhlDraw ; if so, go ahead
- xchg ebx, ecx ; if not, switcharoo...
- xchg esi, edx
-
- zhlDraw:
- mov [ebp].zhlz2, edx ; save the new z2 value to free a register
-
- cmp ecx, 0 ; clip the left end of the line
- jge zhlx1ok
- mov ecx, 0
-
- zhlx1ok:
- cmp ecx, 320 ; see if the left end is off the right side
- jge zhldone ; of the screen
-
- cmp ebx, 319 ; clip the right end of the line
- jl zhlx2ok
- mov ebx, 319
-
- zhlx2ok:
- cmp ebx, 0 ; see if the right end is off the left side
- jl zhldone ; of the screen
-
- mov ebp, zBuf ; get the z-buffer address
-
- add eax, ecx ; calculate starting offset, y * width + x1
- add edi, eax ; starting screen address
- shl eax, 1 ; * 2 for words
- add ebp, eax ; starting z-buffer address
- shr eax, 1 ; / 2 to give us bytes again
-
- ; here I used to check to see if both endpoints of the line were
- ; obscured by other polygons. This may speed things up if you have
- ; a lot of planes stacked on top of each other, but it may also
- ; make intersecting planes display incorrectly
-
- ;cmp esi, [ebp + ecx * 2] ; see if the first endpoint is visible
- ;jl zhlPartVis
-
- ;cmp edx, [ebp + ebx * 2] ; test the 2nd if the first is invis
- ;jg zhlDone
-
- zhlPartVis:
- sub ebx, ecx ; get # of pix to draw
- mov ecx, ebx
-
- jecxz zhlIHATESHORTJUMPS
-
- mov eax, edx ; put z2 in eax
- sub eax, esi ; eax = dz = z2 - z1
- shl eax, 16 ; dz *= 65536, scale to 16.16 fixed point
- cdq ; set up for divide, sign extend eax into edx
- idiv ebx ; get dzdx
-
- jmp zhlGoOn
-
- zhlIHATESHORTJUMPS:
- jmp zhlDone
-
-
- zhlGoOn:
- mov edx, eax ; save dz/dx ratio in edx
- mov ebx, esi ; eax = z1
- shl ebx, 16 ; ebx = z1 * 65536, scaled to 16.16 fixed point
-
- mov eax, cTop ; get stored color (we killed ebp so we can't
- ; get any data off the stack)
-
- jcxz zhlMod ; get out if nothing to draw
-
- ror edx, 16 ; set up ratio for adc (swap low, high words)
- ror ebx, 16 ; set up z1 for adc (swap low, high words)
-
- align 4 ; I was once told this speeds things up...
-
- zhlLoop:
-
- test BYTE PTR [edi], 0FFh ; check to see if pixel is set
- jz zhlDontCheck ; if not, don't check z-buffer
-
- cmp [ebp], bx ; check current z value against z-buffer
- jl zhlNoDisp ; if z-buffer value is less, don't display
-
- zhlDontCheck:
- mov [ebp], bx ; write z value to z-buffer
- mov [edi], al ; write color to screen
-
- zhlNoDisp:
- add ebp, 2 ; next z-buffer address
- inc edi ; next screen address
- add ebx, edx ; add z ratio to current z
- adc ebx, 0 ; add carry flag to complete 16.16 addition
-
- dec ecx ; pixels to draw - 1
- jnz zhlLoop ; loop if any pixels are left to draw
-
- zhlMod:
-
- zhlDone:
- pop edi
- pop esi
- pop ebp
-
- ret 24 ; we outta here...
-
-
- zHline endp
-
-
- ; zbuffer polygon draw
-
- zp3Stack struc
- dd ?,?,? ; room for regs
- dd ? ; caller
- zp3c dd ? ; color
- zp3z3 dd ? ; z3
- zp3y3 dd ? ; y3
- zp3x3 dd ? ; x3
- zp3z2 dd ? ; z2
- zp3y2 dd ? ; y2
- zp3x2 dd ? ; x2
- zp3z1 dd ? ; z1
- zp3y1 dd ? ; y1
- zp3x1 dd ? ; x1
-
- zp3Stack ends
-
- public zpoly3
-
- zpoly3 proc
-
- push ebp
- push edi
- push esi
-
- mov ebp, esp
-
- mov eax, [ebp].zp3y1
- mov ebx, [ebp].zp3y2
- mov ecx, [ebp].zp3y3
-
- ; sort the points based on y values
-
- zyComp1:
- cmp eax, ebx
- jg zy2top
-
- mov yTop, eax ; sort the points, find top, middle,
- mov edx, [ebp].zp3x1 ; and bottom
- mov xTop, edx
- mov edx, [ebp].zp3z1
- mov zTop, edx
-
- mov yBot, ebx
- mov edx, [ebp].zp3x2
- mov xBot, edx
- mov edx, [ebp].zp3z2
- mov zBot, edx
-
- jmp zyComp2
-
- zy2top: mov yTop, ebx
- mov edx, [ebp].zp3x2
- mov xTop, edx
- mov edx, [ebp].zp3z2
- mov zTop, edx
-
- mov yBot, eax
- mov edx, [ebp].zp3x1
- mov xBot, edx
- mov edx, [ebp].zp3z1
- mov zBot, edx
-
- zyComp2:
- cmp ecx, yTop
- jg zyTopOK
-
- mov yTop, ecx
- mov edx, [ebp].zp3x3
- mov xTop, edx
- mov edx, [ebp].zp3z3
- mov zTop, edx
-
- cmp eax, ebx
- jg zy2mid
-
- mov yMid, eax
- mov edx, [ebp].zp3x1
- mov xMid, edx
- mov edx, [ebp].zp3z1
- mov zMid, edx
-
- mov yBot, ebx
- mov edx, [ebp].zp3x2
- mov xBot, edx
- mov edx, [ebp].zp3z2
- mov zBot, edx
-
-
- jmp zyCompDone
-
- zy2mid: mov yMid, ebx
- mov edx, [ebp].zp3x2
- mov xMid, edx
- mov edx, [ebp].zp3z2
- mov zMid, edx
-
- mov yBot, eax
- mov edx, [ebp].zp3x1
- mov xBot, edx
- mov edx, [ebp].zp3z1
- mov zBot, edx
-
- jmp zyCompDone
-
- zyTopOK:
- cmp ecx, yBot
- jg zybBad
-
- mov yMid, ecx
- mov edx, [ebp].zp3x3
- mov xMid, edx
- mov edx, [ebp].zp3z3
- mov zMid, edx
-
- jmp zyCompDone
-
- zybBad: mov eax, yBot
- mov ebx, xBot
- mov edx, zBot
-
- mov yMid, eax
- mov xMid, ebx
- mov zMid, edx
-
- mov yBot, ecx
- mov edx, [ebp].zp3x3
- mov xBot, edx
- mov edx, [ebp].zp3z3
- mov zBot, edx
-
-
- zyCompDone:
-
- mov eax, yTop ; don't draw the polygon if its top is below
- mov ebx, yBot ; the bottom of the screen, or if it's
- cmp eax, 199 ; bottom is above the top of the screen
- jg zfillDone
- cmp ebx, 0
- jl zfillDone
-
- ; now calculate the x values at each scanline for the longest side.
-
- mov eax, xBot
- mov ebx, xTop
- sub eax, ebx ; calculate dx
- shl eax, 16
-
- mov ecx, yBot
- mov edx, yTop
- sub ecx, edx ; calculate dy
-
- jecxz zedge1Horz ; skip the div if dy = 0
-
- cdq ; sign extend eax into edx, set up for idiv
- idiv ecx ; OOOH, SLOOW
-
- jmp zedge1Continue
-
- zedge1Horz:
-
- jmp zedge2Start ; forget the div if dy = 0
-
- zedge1Continue:
-
- mov ecx, yBot
- mov ebx, yTop
- sub ecx, ebx ; # of scanlines to trace
-
- shl ebx, 2 ; y1 * 4, offset into dword edgelist
- lea edi, lEdge ; load edgelist
- add edi, ebx ; add starting offset
-
- xor ebx, ebx
- mov edx, xTop ; starting x value
- mov esi, yTop ; starting y value
-
- ror eax, 16 ; set up dx/dy for 16.16 fixed point adc
-
- align 4
-
- zedge1Loop:
-
- cmp esi, 0 ; crude form of clipping
- jl zskipThisLine1
-
- cmp esi, 199
- jg zedge2Start
-
- mov bx, dx ; move integer part of x into bx
- mov [edi], ebx ; store a dword in the edge list
-
- zskipThisLine1:
-
- add edx, eax ; add ratio to x
- adc edx, 0 ; carry flag completes addition
- add edi, 4 ; next scanline in edge list
- inc esi ; y++
- dec ecx ; scanlines to draw --
- jns zedge1Loop
-
- ; calculate x values for next side
-
- zedge2Start:
-
- mov eax, xBot
- mov ebx, xMid
- sub eax, ebx
- shl eax, 16
-
- mov ecx, yBot
- mov edx, yMid
- sub ecx, edx
-
- jecxz zedge2Horz
-
- cdq
- idiv ecx
-
- jmp zedge2Continue
-
- zedge2Horz:
-
- jmp zedge3Start
-
- zedge2Continue:
-
- mov ecx, yBot
- mov ebx, yMid
- sub ecx, ebx
-
- shl ebx, 2
- lea edi, rEdge
- add edi, ebx
-
- xor ebx, ebx
- mov edx, xMid
- mov esi, yMid
-
- ror eax, 16
-
- align 4
-
- zedge2Loop:
-
- cmp esi, 0
- jl zskipThisLine2
- cmp esi, 199
- jg zedge3Start
-
- mov bx, dx
- mov [edi], ebx
-
- zskipThisLine2:
-
- add edx, eax
- adc edx, 0
- add edi, 4
- inc esi
- dec ecx
- jns zedge2Loop
-
- ; calculate x values for last side
-
- zedge3Start:
-
- mov eax, xMid
- mov ebx, xTop
- sub eax, ebx
- shl eax, 16
-
- mov ecx, yMid
- mov edx, yTop
- sub ecx, edx
-
- jecxz zedge3Horz
-
- cdq
- idiv ecx
-
- jmp zedge3Continue
-
- zedge3Horz:
-
- jmp zcolorStartc
-
- zedge3Continue:
-
- mov ecx, yMid
- mov ebx, yTop
- sub ecx, ebx
-
- shl ebx, 2
- lea edi, rEdge
- add edi, ebx
-
- xor ebx, ebx
- mov edx, xTop
- mov esi, yTop
-
- ror eax, 16
-
- align 4
-
- zedge3Loop:
-
- cmp esi, 0
- jl zskipThisLine3
-
- cmp esi, 199
- jg zcolorStartc
-
- mov bx, dx
- mov [edi], ebx
-
- zskipThisLine3:
-
- add edx, eax
- adc edx, 0
- add edi, 4
- inc esi
- dec ecx
- jns zedge3Loop
-
- zcolorStartc:
-
- ; now calculate the color values at each scanline for the longest side.
-
- mov eax, zBot
- mov ebx, zTop
- sub eax, ebx
- shl eax, 16
-
- mov ecx, yBot
- mov edx, yTop
- sub ecx, edx
-
- jecxz zedge1Horzc ; skip the div if denominator = 0
-
- cdq
- idiv ecx
-
- jmp zedge1Continuec
-
- zedge1Horzc:
-
- jmp zedge2Startc
-
- zedge1Continuec:
-
- mov ecx, yBot
- mov ebx, yTop
- sub ecx, ebx
-
- shl ebx, 2
- lea edi, lZ
- add edi, ebx
-
- xor ebx, ebx
- mov edx, zTop
- mov esi, yTop
-
- ror eax, 16
-
- align 4
-
- zedge1Loopc:
-
- cmp esi, 0
- jl zskipThisLine1c
-
- cmp esi, 199
- jg zedge2Startc
-
- mov bx, dx
- mov [edi], ebx
-
- zskipThisLine1c:
-
- add edx, eax
- adc edx, 0
- add edi, 4
- inc esi
- dec ecx
- jns zedge1Loopc
-
- zedge2Startc:
-
- mov eax, zBot
- mov ebx, zMid
- sub eax, ebx
- shl eax, 16
-
- mov ecx, yBot
- mov edx, yMid
- sub ecx, edx
-
- jecxz zedge2Horzc
-
- cdq
- idiv ecx
-
- jmp zedge2Continuec
-
- zedge2Horzc:
-
- jmp zedge3Startc
-
- zedge2Continuec:
-
- mov ecx, yBot
- mov ebx, yMid
- sub ecx, ebx
-
- shl ebx, 2
- lea edi, rZ
- add edi, ebx
-
- xor ebx, ebx
- mov edx, zMid
- mov esi, yMid
-
- ror eax, 16
-
- align 4
-
- zedge2Loopc:
-
- cmp esi, 0
- jl zskipThisLine2c
-
- cmp esi, 199
- jg zedge3Startc
-
- mov bx, dx
- mov [edi], ebx
-
- zskipThisLine2c:
-
- add edx, eax
- adc edx, 0
- add edi, 4
- inc esi
- dec ecx
- jns zedge2Loopc
-
- ; calculate z values for the last side
-
- zedge3Startc:
-
- mov eax, zMid
- mov ebx, zTop
- sub eax, ebx
- shl eax, 16
-
- mov ecx, yMid
- mov edx, yTop
- sub ecx, edx
-
- jecxz zedge3Horzc
-
- cdq
- idiv ecx
-
- jmp zedge3Continuec
-
- zedge3Horzc:
-
- jmp zfillStart
-
- zedge3Continuec:
-
- mov ecx, yMid
- mov ebx, yTop
- sub ecx, ebx
-
- shl ebx, 2
- lea edi, rZ
- add edi, ebx
-
- xor ebx, ebx
- mov edx, zTop
- mov esi, yTop
-
- ror eax, 16
-
- align 4
-
- zedge3Loopc:
-
- cmp esi, 0
- jl zskipThisLine3c
-
- cmp esi, 199
- jg zfillStart
-
- mov bx, dx
- mov [edi], ebx
-
- zskipThisLine3c:
-
- add edx, eax
- adc edx, 0
- add edi, 4
- inc esi
- dec ecx
- jns zedge3Loopc
-
- ; time to fill...
-
- zfillStart:
-
- mov eax, yTop
- mov ebx, yBot
-
- cmp eax, 0
- jge zcheckBot
- xor eax, eax
- mov yTop, eax
-
- zcheckBot:
-
- cmp ebx, 199
- jle zfillNOW
- mov ebx, 199
- mov yBot, ebx
-
- zfillNOW:
-
- lea esi, lEdge
- lea edi, rEdge
-
- lea eax, lZ
- lea edx, rZ
-
- mov ecx, yTop
- shl ecx, 2
-
- add esi, ecx
- add edi, ecx
- add eax, ecx
- add edx, ecx
-
- shr ecx, 2
-
- align 4
-
- zfillME: push ecx
-
- zx1OKToo:
- push esi ; save important registers
- push eax
- push edi
- push edx
-
- push [esi] ; push arguments on stack
- push [eax]
- push [edi]
- push [edx]
- push ecx
- push [ebp].zp3c
-
- call zHline ; draw a horizontal line
-
- pop edx ; restore important schtuff
- pop edi
- pop eax
- pop esi
-
- znextLine:
- pop ecx
-
- add esi, 4 ; go to next element in all lists
- add edi, 4
- add eax, 4
- add edx, 4
-
- inc ecx ; y++
- cmp ecx, yBot ; see if we're done yet
- jle zfillME ; back to work!
-
- zfillDone:
-
- pop esi
- pop edi
- pop ebp
-
- ret 40 ; see ya...
-
- zpoly3 endp
-
-
- ; zbuffer gouraud hline draw
-
- gzhlStack struc
-
- dd ?,?,? ; ebp esi edi
- dd ? ; caller
- gzhly dd ? ; y
- gzhlc2 dd ? ; c2
- gzhlz2 dd ? ; z2
- gzhlx2 dd ? ; x2
- gzhlc1 dd ? ; c1
- gzhlz1 dd ? ; z1
- gzhlx1 dd ? ; x1
-
- gzhlStack ends
-
-
- ; gzHline draws a gouraud shaded z-buffered horizontal line between <x1,z1,c1>
- ; and <x2,z2,c2>. This code is very similar to the zHline routine, with the
- ; exception that I interpolate color values as well as z values.
-
-
- public gzHline
-
- gzHline proc ; zbuffered hline routine
-
- push ebp
- push esi
- push edi
- mov ebp, esp
-
- mov eax, [ebp].gzhlc1 ; save the color values cause we're gonna
- mov cBot, eax ; trash ebp later on
- mov eax, [ebp].gzhlc2
- mov cTop, eax
-
- mov eax, [ebp].gzhly ; y value
-
- lea eax, [eax + eax*4] ; eax = eax * 320
- shl eax, 6
-
- push eax ; save the offset for later
-
- mov edi, curPage ; get current video page
-
- mov ecx, [ebp].gzhlx1 ; get x's and z's
- mov ebx, [ebp].gzhlx2
- mov esi, [ebp].gzhlz1
- mov edx, [ebp].gzhlz2
-
- movsx ecx, cx ; sign extend 16 bit values into 32 bit regs
- movsx ebx, bx
- movsx esi, si
- movsx edx, dx
-
- cmp ebx, ecx ; make sure x2 > x1
- jg gzhlDraw ; if so, keep going
- xchg ebx, ecx ; if not, switch everything
- xchg esi, edx
- mov eax, cTop
- mov temp, eax
- mov eax, cBot
- mov cTop, eax
- mov eax, temp
- mov cBot, eax
-
- gzhlDraw:
- mov [ebp].gzhlz2, edx ; free a register by saving it on the stack
-
- cmp ecx, 0 ; clip the left edge
- jg gzhlx1ok
- mov ecx, 0
-
- gzhlx1ok:
- cmp ecx, 320 ; quit if left edge is off the right side of
- jl gzhlx1small ; the screen
- pop eax
- jmp gzhlDone
-
- gzhlx1small:
-
- cmp ebx, 319 ; clip the right edge
- jl gzhlx2ok
- mov ebx, 319
-
- gzhlx2ok:
- cmp ebx, 0 ; quit if right edge is off the left side of
- jg gzhlx2big ; the screen
- pop eax
- jmp gzhlDone
-
- gzhlx2big:
-
- mov ebp, zBuf ; get the z-buffer
-
- pop eax ; get the saved offset
-
- add eax, ecx ; starting offset + x1
- add edi, eax ; starting offset into screen
- shl eax, 1 ; * 2 for words
- add ebp, eax ; starting offset into z-buffer
- shr eax, 1 ; back to bytes
-
- sub ebx, ecx ; get # of pix to draw
- mov ecx, ebx
-
- jecxz gzhlIHATESHORTJUMPS
-
- mov eax, edx ; get z1
- sub eax, esi ; z2 - z1
- shl eax, 16 ; dz *= 65536, convert to 16.16 fixed point
-
- cdq ; sign extend eax into edx for divide
- idiv ebx ; get dz/dx
-
- mov temp, eax ; save ratio (dz/dx)
-
- ; comment out this block if you want to use a constant dc/dx for the
- ; entire polygon. This eliminates one idiv per scanline, but there
- ; is a noticable decrease in quality. In my opinion, the added
- ; quality given by the idiv is worth a slight slowdown
-
- mov edx, cBot ; get c1
- mov eax, cTop ; get c2
- sub eax, edx ; c2 - c1
- shl eax, 8 ; dc *= 256
-
- cdq ; sign extend before divide
- idiv ebx ; eax = dc/dx
-
- ; uncomment the next line to get the constant ratio for the plane
-
- ;mov eax, cRatio
-
- jmp gzhlGoOn
-
- gzhlIHATESHORTJUMPS:
- jmp gzhlDone
-
-
- gzhlGoOn:
- mov edx, temp ; edx = dzdx * 65536
- mov ebx, esi ; ebx = z1
- shl ebx, 16 ; ebx *= 65536
-
- mov esi, eax ; esi = dcdx * 256
- mov eax, cBot ; eax = c1
- shl eax, 8 ; c1 *= 256
-
- cmp ecx, 0
- jz gzhlDone ; get out if nothing to draw
-
- rol ebx, 16 ; convert z1 to be used with 16.16 adc
- rol edx, 16 ; convert dz/dx to be used with 16.16 adc
-
- ; eax = c1 << 8
- ; ebx = z1 << 16
- ; ecx = count
- ; edx = dz/dx << 16
- ; esi = dc/dx << 8
- ; edi = [screen]
- ; ebp = [zbuf]
-
- align 4
-
- gzhlByteLoop:
-
- ; HEY MainFrame! Uncomment the next two lines to do z-clipping. The
- ; problem with z-clipping is that I use words in the z-buffer, so I
- ; clip at 0, 64k, 128k, etc. IT IS TOTALLY WORTHLESS :)
-
- ;cmp bx, 0 ; don't draw anything behind the eye
- ;jl gzhlNoDisp
-
- test BYTE PTR [edi], 0FFh ; check to see if the pixel is set
- jz gzhlDontCheck ; if not, don't bother checking the zbuffer
-
- cmp [ebp], bx ; check z-buffer value
- jl gzhlNoDisp
-
- gzhlDontCheck:
- mov [ebp], bx ; write to the z-buffer
- mov [edi], ah ; write to the screen
-
- gzhlNoDisp:
- add ebp, 2 ; next z-buffer address
- inc edi ; next screen address
- add ebx, edx ; z + dz
- adc ebx, 0 ; add carry flag to complete 16.16 addition
- add eax, esi ; c + dc
-
- dec ecx ; pixToDraw - 1
- jnz gzhlByteLoop ; draw som mo'
-
- gzhlMod:
-
- gzhlDone:
- pop edi
- pop esi
- pop ebp
-
- ret 28
-
-
- gzhline endp
-
-
- ; This routine draws a gouraud shaded z-buffered fully clipped polygon,
- ; sales tax and 25% royalty to the author not included. It is VERY similar
- ; to the zpoly3 routine, with the exception that z is traced along with c
- ; and x. Because of the similarities, I am not going to comment this
- ; routine as thouroughly as I did zpoly3
-
-
- ; zbuffer gouraud polygon draw
-
- gzp3Stack struc
- dd ?,?,? ; room for regs
- dd ? ; caller
- gzp3c3 dd ? ; c3
- gzp3z3 dd ? ; z3
- gzp3y3 dd ? ; y3
- gzp3x3 dd ? ; x3
- gzp3c2 dd ? ; c2
- gzp3z2 dd ? ; z2
- gzp3y2 dd ? ; y2
- gzp3x2 dd ? ; x2
- gzp3c1 dd ? ; c1
- gzp3z1 dd ? ; z1
- gzp3y1 dd ? ; y1
- gzp3x1 dd ? ; x1
-
- gzp3Stack ends
-
- public gzpoly3
-
- gzpoly3 proc
-
- push ebp
- push edi
- push esi
-
- mov ebp, esp
-
- mov eax, [ebp].gzp3y1
- mov ebx, [ebp].gzp3y2
- mov ecx, [ebp].gzp3y3
-
- ; sort the points based on y values
-
- gzyComp1:
- cmp eax, ebx
- jg gzy2top
-
- mov yTop, eax ; do the ol' sorting thing, find top, middle,
- mov edx, [ebp].gzp3x1 ; and bottom vertices
- mov xTop, edx
- mov edx, [ebp].gzp3z1
- mov zTop, edx
- mov edx, [ebp].gzp3c1
- mov cTop, edx
-
- mov yBot, ebx
- mov edx, [ebp].gzp3x2
- mov xBot, edx
- mov edx, [ebp].gzp3z2
- mov zBot, edx
- mov edx, [ebp].gzp3c2
- mov cBot, edx
-
- jmp gzyComp2
-
- gzy2top:
- mov yTop, ebx
- mov edx, [ebp].gzp3x2
- mov xTop, edx
- mov edx, [ebp].gzp3z2
- mov zTop, edx
- mov edx, [ebp].gzp3c2
- mov cTop, edx
-
- mov yBot, eax
- mov edx, [ebp].gzp3x1
- mov xBot, edx
- mov edx, [ebp].gzp3z1
- mov zBot, edx
- mov edx, [ebp].gzp3c1
- mov cBot, edx
-
- gzyComp2:
- cmp ecx, yTop
- jg gzyTopOK
-
- mov yTop, ecx
- mov edx, [ebp].gzp3x3
- mov xTop, edx
- mov edx, [ebp].gzp3z3
- mov zTop, edx
- mov edx, [ebp].gzp3c3
- mov cTop, edx
-
- cmp eax, ebx
- jg gzy2mid
-
- mov yMid, eax
- mov edx, [ebp].gzp3x1
- mov xMid, edx
- mov edx, [ebp].gzp3z1
- mov zMid, edx
- mov edx, [ebp].gzp3c1
- mov cMid, edx
-
- mov yBot, ebx
- mov edx, [ebp].gzp3x2
- mov xBot, edx
- mov edx, [ebp].gzp3z2
- mov zBot, edx
- mov edx, [ebp].gzp3c2
- mov cBot, edx
-
-
- jmp gzyCompDone
-
- gzy2mid:
- mov yMid, ebx
- mov edx, [ebp].gzp3x2
- mov xMid, edx
- mov edx, [ebp].gzp3z2
- mov zMid, edx
- mov edx, [ebp].gzp3c2
- mov cMid, edx
-
- mov yBot, eax
- mov edx, [ebp].gzp3x1
- mov xBot, edx
- mov edx, [ebp].gzp3z1
- mov zBot, edx
- mov edx, [ebp].gzp3c1
- mov cBot, edx
-
- jmp gzyCompDone
-
- gzyTopOK:
- cmp ecx, yBot
- jg gzybBad
-
- mov yMid, ecx
- mov edx, [ebp].gzp3x3
- mov xMid, edx
- mov edx, [ebp].gzp3z3
- mov zMid, edx
- mov edx, [ebp].gzp3c3
- mov cMid, edx
-
- jmp gzyCompDone
-
- gzybBad:
- mov eax, yBot
- mov ebx, xBot
- mov edx, zBot
- mov esi, cBot
-
- mov yMid, eax
- mov xMid, ebx
- mov zMid, edx
- mov cMid, esi
-
- mov yBot, ecx
- mov edx, [ebp].gzp3x3
- mov xBot, edx
- mov edx, [ebp].gzp3z3
- mov zBot, edx
- mov edx, [ebp].gzp3c3
- mov cBot, edx
-
-
- gzyCompDone:
-
- mov eax, yTop ; get y1
- mov ebx, yBot ; get y2
- cmp eax, 199 ; get out if top is below the screen bottom
- jg gzfillDone
- cmp ebx, 0 ; get out if bottom is above screen top
- jl gzfillDone
-
- ; now calculate the x values at each scanline for the longest side.
-
- mov eax, xBot
- mov ebx, xTop
- sub eax, ebx ; calculate dx
- shl eax, 16
-
- mov ecx, yBot
- mov edx, yTop
- sub ecx, edx ; calculate dy
-
- jecxz gzedge1Horz ; skip the div if dy = 0
-
- cdq
- idiv ecx ; calcualte dx/dy
-
- jmp gzedge1Continue
-
- gzedge1Horz:
-
- jmp gzedge2Start
-
- gzedge1Continue:
- mov ecx, yBot
- mov ebx, yTop
- sub ecx, ebx ; # of scanlines to trace
-
- shl ebx, 2 ; starting offset into edgelist
- lea edi, lEdge ; load edgelist
- add edi, ebx ; go to start of this side
-
- xor ebx, ebx
- mov edx, xTop ; x1
- mov esi, yTop ; y1
-
- ror eax, 16 ; set up for 16.16 fixed point adc
-
- align 4
-
- gzedge1Loop:
-
- cmp esi, 0
- jl gzskipThisLine1 ; clip the top of this edge
-
- cmp esi, 199 ; clip the bottom of this edge
- jg gzedge2Start
-
- mov bx, dx ; move integer part of edx into bx
- mov [edi], ebx ; store ebx in edgelist
-
- gzskipThisLine1:
-
- add edx, eax ; add ratio to x
- adc edx, 0 ; carry flag completes 16.16 addition
- add edi, 4 ; next element in edgelist
- inc esi ; next scanline
- dec ecx ; linesToDo --
- jns gzedge1Loop ; do som mo'!
-
- ; calculate x values for next side
-
- gzedge2Start: ; the scan conversion process outlined above
- ; is repeated for all edges, scanning x,
- mov eax, xBot ; color, and z values. IT IS ALL DONE
- mov ebx, xMid ; EXACTLY AS IT IS DONE ABOVE
- sub eax, ebx
- shl eax, 16
-
- mov ecx, yBot
- mov edx, yMid
- sub ecx, edx
-
- jecxz gzedge2Horz
-
- cdq
- idiv ecx
-
- jmp gzedge2Continue
-
- gzedge2Horz:
-
- jmp gzedge3Start
-
- gzedge2Continue:
- mov ecx, yBot
- mov ebx, yMid
- sub ecx, ebx
-
- shl ebx, 2
- lea edi, rEdge
- add edi, ebx
-
- xor ebx, ebx
- mov edx, xMid
- mov esi, yMid
-
- ror eax, 16
-
- align 4
-
- gzedge2Loop:
-
- cmp esi, 0
- jl gzskipThisLine2
-
- cmp esi, 199
- jg gzedge3Start
-
- mov bx, dx
- mov [edi], ebx
-
- gzskipThisLine2:
-
- add edx, eax
- adc edx, 0
- add edi, 4
- inc esi
- dec ecx
- jns gzedge2Loop
-
- ; calculate x values for last side
-
- gzedge3Start:
-
- mov eax, xMid
- mov ebx, xTop
- sub eax, ebx
- shl eax, 16
-
- mov ecx, yMid
- mov edx, yTop
- sub ecx, edx
-
- jecxz gzedge3Horz
-
- cdq
- idiv ecx
-
- jmp gzedge3Continue
-
- gzedge3Horz:
-
- jmp gzcolorStartc
-
- gzedge3Continue:
-
- mov ecx, yMid
- mov ebx, yTop
- sub ecx, ebx
-
- shl ebx, 2
- lea edi, rEdge
- add edi, ebx
-
- xor ebx, ebx
- mov edx, xTop
- mov esi, yTop
-
- ror eax, 16
-
- align 4
-
- gzedge3Loop:
-
- cmp esi, 0
- jl gzskipThisLine3
- cmp esi, 199
- jg gzcolorStartc
-
- mov bx, dx
- mov [edi], ebx
-
- gzskipThisLine3:
-
- add edx, eax
- adc edx, 0
- add edi, 4
- inc esi
- dec ecx
- jns gzedge3Loop
-
- gzcolorStartc:
-
- ; now calculate the z values at each scanline for the longest side.
-
- mov eax, zBot
- mov ebx, zTop
- sub eax, ebx
- shl eax, 16
-
- mov ecx, yBot
- mov edx, yTop
- sub ecx, edx
-
- jecxz gzedge1Horzc ; skip the div if denominator = 0
-
- cdq
- idiv ecx
-
- jmp gzedge1Continuec
-
- gzedge1Horzc:
-
- jmp gzedge2Startc
-
- gzedge1Continuec:
-
- mov ecx, yBot
- mov ebx, yTop
- sub ecx, ebx
-
- shl ebx, 2
-
- lea edi, lZ
- add edi, ebx
-
- xor ebx, ebx
- mov edx, zTop
- mov esi, yTop
-
- ror eax, 16
-
- align 4
-
- gzedge1Loopc:
-
- cmp esi, 0
- jl gzskipThisLine1c
-
- cmp esi, 199
- jg gzedge2Startc
-
- mov bx, dx
- mov [edi], ebx
-
- gzskipThisLine1c:
-
- add edx, eax
- adc edx, 0
- add edi, 4
- inc esi
- dec ecx
- jns gzedge1Loopc
-
- ; calculate x values for next side
-
- gzedge2Startc:
-
- mov eax, zBot
- mov ebx, zMid
- sub eax, ebx
- shl eax, 16
-
- mov ecx, yBot
- mov edx, yMid
- sub ecx, edx
-
- jecxz gzedge2Horzc
-
- cdq
- idiv ecx
-
- jmp gzedge2Continuec
-
- gzedge2Horzc:
-
- jmp gzedge3Startc
-
- gzedge2Continuec:
-
- mov ecx, yBot
- mov ebx, yMid
- sub ecx, ebx
-
- shl ebx, 2
- lea edi, rZ
- add edi, ebx
-
- xor ebx, ebx
- mov edx, zMid
- mov esi, yMid
-
- ror eax, 16
-
- align 4
-
- gzedge2Loopc:
-
- cmp esi, 0
- jl gzskipThisLine2c
-
- cmp esi, 199
- jg gzedge3Startc
-
- mov bx, dx
- mov [edi], ebx
-
- gzskipThisLine2c:
-
- add edx, eax
- adc edx, 0
- add edi, 4
- inc esi
- dec ecx
- jns gzedge2Loopc
-
- ; calculate x values for last side
-
- gzedge3Startc:
-
- mov eax, zMid
- mov ebx, zTop
- sub eax, ebx
- shl eax, 16
-
- mov ecx, yMid
- mov edx, yTop
- sub ecx, edx
-
- jecxz gzedge3Horzc
-
- cdq
- idiv ecx
-
- jmp gzedge3Continuec
-
- gzedge3Horzc:
-
- jmp gcolorStartcz
-
- gzedge3Continuec:
-
- mov ecx, yMid
- mov ebx, yTop
- sub ecx, ebx
-
- shl ebx, 2
- lea edi, rZ
- add edi, ebx
-
- xor ebx, ebx
- mov edx, zTop
- mov esi, yTop
-
- ror eax, 16
-
- align 4
-
- gzedge3Loopc:
-
- cmp esi, 0
- jl gzskipThisLine3c
-
- cmp esi, 199
- jg gcolorStartcz
-
- mov bx, dx
- mov [edi], ebx
-
- gzskipThisLine3c:
-
- add edx, eax
- adc edx, 0
- add edi, 4
- inc esi
- dec ecx
- jns gzedge3Loopc
-
- gcolorStartcz:
-
- ; now calculate the color values at each scanline for the longest side.
-
- mov eax, cBot
- mov ebx, cTop
- sub eax, ebx
- shl eax, 16
-
- mov ecx, yBot
- mov edx, yTop
- sub ecx, edx
-
- jecxz gedge1Horzcz ; skip the div if denominator = 0
-
- cdq
- idiv ecx
-
- jmp gedge1Continuecz
-
- gedge1Horzcz:
-
- jmp gedge2Startcz
-
- gedge1Continuecz:
-
- mov ecx, yBot
- mov ebx, yTop
- sub ecx, ebx
-
- shl ebx, 2
- lea edi, lColor
- add edi, ebx
-
- xor ebx, ebx
- mov edx, cTop
- mov esi, yTop
-
- ror eax, 16
-
- align 4
-
- gedge1Loopcz:
-
- cmp esi, 0
- jl gskipThisLine1cz
-
- cmp esi, 199
- jg gedge2Startcz
-
- mov bx, dx
- mov [edi], ebx
-
- gskipThisLine1cz:
-
- add edx, eax
- adc edx, 0
- add edi, 4
- inc esi
- dec ecx
- jns gedge1Loopcz
-
- ; calculate x values for next side
-
- gedge2Startcz:
-
- mov eax, cBot
- mov ebx, cMid
- sub eax, ebx
- shl eax, 16
-
- mov ecx, yBot
- mov edx, yMid
- sub ecx, edx
-
- jecxz gedge2Horzcz
-
- cdq
- idiv ecx
-
- jmp gedge2Continuecz
-
- gedge2Horzcz:
-
- jmp gedge3Startcz
-
- gedge2Continuecz:
-
- mov ecx, yBot
- mov ebx, yMid
- sub ecx, ebx
-
- shl ebx, 2
- lea edi, rColor
- add edi, ebx
-
- xor ebx, ebx
- mov edx, cMid
- mov esi, yMid
-
- ror eax, 16
-
- align 4
-
- gedge2Loopcz:
-
- cmp esi, 0
- jl gskipThisLine2cz
-
- cmp esi, 199
- jg gedge3Startcz
-
- mov bx, dx
- mov [edi], ebx
-
- gskipThisLine2cz:
-
- add edx, eax
- adc edx, 0
- add edi, 4
- inc esi
- dec ecx
- jns gedge2Loopcz
-
- ; calculate x values for last side
-
- gedge3Startcz:
-
- mov eax, cMid
- mov ebx, cTop
- sub eax, ebx
- shl eax, 16
-
- mov ecx, yMid
- mov edx, yTop
- sub ecx, edx
-
- jecxz gedge3Horzcz
-
- cdq
- idiv ecx
-
- jmp gedge3Continuecz
-
- gedge3Horzcz:
-
- jmp gzfillStart
-
- gedge3Continuecz:
-
- mov ecx, yMid
- mov ebx, yTop
- sub ecx, ebx
-
- shl ebx, 2
- lea edi, rColor
- add edi, ebx
-
- xor ebx, ebx
- mov edx, cTop
- mov esi, yTop
-
- ror eax, 16
-
- align 4
-
- gedge3Loopcz:
-
- cmp esi, 0
- jl gskipThisLine3cz
- cmp esi, 199
- jg gzfillStart
-
- mov bx, dx
- mov [edi], ebx
-
- gskipThisLine3cz:
-
- add edx, eax
- adc edx, 0
- add edi, 4
- inc esi
- dec ecx
- jns gedge3Loopcz
-
- ; time to fill...
-
- gzfillStart:
-
- mov eax, yTop
- mov ebx, yBot
-
- cmp eax, 0
- jge gzcheckBot
- xor eax, eax
- mov yTop, eax
-
- gzcheckBot:
- cmp ebx, 199
- jle gzfillNOW
-
- mov ebx, 199
- mov yBot, ebx
-
- gzfillNOW:
- lea esi, lEdge ; load edgelists
- lea edi, rEdge
-
- lea eax, lColor
- lea edx, rColor
-
- mov ecx, yMid ; midpoint
-
- mov esi, [esi + ecx*4] ; find x values at midpoint
- mov edi, [edi + ecx*4]
-
- mov eax, [eax + ecx*4] ; find color values at midpoint
- mov edx, [edx + ecx*4]
-
- sub eax, edx ; get dc
- sub esi, edi ; get dx
- test esi, 0FFFFFFFFh ; make sure dx != 0
- jnz gzcrDiv
-
- mov eax, 0
- mov cRatio, eax
- jmp gzcrNodiv
-
- gzcrDiv:
- shl eax, 8 ; scale to 8.8 fixed point
- cdq ; get ready for div
- idiv esi ; calculate dc/dx used as the constant
- mov cRatio, eax ; color/x ratio for this plane
-
- gzcrNodiv:
- lea esi, lEdge ; load edgelists again
- lea edi, rEdge
-
- lea eax, lColor
- lea edx, rColor
-
- lea ebx, lZ
- lea ebp, rZ
-
- mov ecx, yTop ; starting y value
- shl ecx, 2 ; *4 to make an index into dword lists
-
- add esi, ecx ; add starting offset to edgelist
- add edi, ecx ; pointers
- add eax, ecx
- add edx, ecx
- add ebx, ecx
- add ebp, ecx
-
- shr ecx, 2 ; /4 to get back to scanlines
-
- align 4
-
- gzfillME: push ecx
-
-
- gzx1OKToo:
- push esi ; save important registers
- push eax
- push edi
- push edx
- push ebx
- push ebp
-
- push [esi] ; push a LOT of arguments onto the
- push [ebx] ; stack for the procedure call
- push [eax]
- push [edi]
- push [ebp]
- push [edx]
- push ecx
-
- call gzHline ; draw a line
-
- pop ebp ; restore important registers
- pop ebx
- pop edx
- pop edi
- pop eax
- pop esi
-
- gznextLine:
- pop ecx ; restore line counter
-
- add esi, 4 ; next element in edgelists
- add edi, 4
- add eax, 4
- add edx, 4
- add ebx, 4
- add ebp, 4
-
- inc ecx ; next scanline
- cmp ecx, yBot ; are we done?
- jle gzfillME ; draw mo', foo'!
-
- gzfillDone:
-
- pop esi
- pop edi
- pop ebp
-
- ret 48 ; DONE!
-
- gzpoly3 endp
-
- end ; end of code (the ONLY) segment
-
-